#pragma once

#include <iostream>
#include <memory>
#include <sys/wait.h>
#include<functional>
#include "Socket.hpp"

namespace TcpServerModule
{
	using namespace SocketModule;
	using namespace LogModule;
	using tcphandler_t = std::function<bool(SockPtr,InetAddr)>; // 客户端文件描述符，客户端地址

	// 只负责流式的IO，不对协议进行任何处理
	class TcpServer
	{
	public:
		TcpServer(int port)
			:_listensockp(std::make_unique<TcpSocket>())
			,_running(false)
			,_port(port)
		{}

		void InitServer(tcphandler_t handler)
		{
			_handler = handler;
			_listensockp->BuildTcpSocket(_port); 
		}
		void Loop() // 循环
		{
			_running = true;
			while(_running)
			{
				// 1.获取连接 Accept
				InetAddr client_addr;
				auto sockfd = _listensockp->ToAccept(&client_addr);
				if(sockfd == nullptr) continue;

				// 2.IO处理
				LOG(LogLevel::DEBUG) << "HttpServer: get a new client,info is: " << client_addr.Addr();
				// sockfd->Recv();
				// sockfd->Send();


				// 多进程处理客户端需求
				pid_t id = fork();
				if(id == 0)
				{
					_listensockp->Close(); // 子进程不需要监听套接字
					if(fork() > 0) 
						exit(0);

					_handler(sockfd,client_addr); // 调用业务处理回调
					exit(0);
				}
				sockfd->Close();		// 父进程关闭客户端套接字
				waitpid(id,nullptr,0);	// 等待子进程退出
			}

			_running = false;
		}
		~TcpServer()
		{
			_listensockp->Close();
		}

	private:
		std::unique_ptr<Socket> _listensockp;	// 监听套接字
		bool _running;
		tcphandler_t _handler;
		int _port;
	};
}